home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 151-175 / scopedisk168 / tinytools / tee / tee.asm < prev    next >
Assembly Source File  |  1995-03-19  |  5KB  |  198 lines

  1. ; Tee, split stdinput to stdoutput and multiple file streams.
  2.  
  3.        INCLUDE "/include/init.i"
  4.  
  5. ; Local Equs
  6.  
  7. BufSize                EQU     512
  8. Handles                EQU     BufSize
  9.  
  10. ; Variable storage
  11.  
  12.        STRUCT  ArgArray,(2+1)*4                ; +1 'cause I'm parnoid
  13.        SIZE
  14.  
  15. ; Regs
  16.  
  17. AppendBool     EQUR    D4
  18. StdInput       EQUR    D5
  19. AllocStruct    EQUR    D6
  20. ActualLength   EQUR    D7
  21.  
  22. FileNamePtrPtr EQUR    A2
  23. HandlePtr      EQUR    A3
  24. ErrorStrPtr    EQUR    A4
  25.  
  26. ; Start
  27.  
  28.        STACK   4000
  29.        INIT
  30.  
  31. ; Let ARP interpret the commandline
  32.  
  33.        MOVE.L  ComLineBase(GP),A0
  34.        MOVE.L  ComLineSize(GP),D0
  35.        LEA     HelpMsg(PC),A1
  36.        LEA     ArgArray(GP),A2
  37.        LEA     Template(PC),A3
  38.        MOVE.L  A1,(A2)
  39.        CALL    GADS
  40.        TST.L   D0
  41.        BEQ.S   UnusableArgs
  42.        BPL.S   ArgsMightBeOK
  43. UnusableArgs:
  44.        MOVE.L  (A2),ErrorStrPtr
  45.        BRA     ErrorExit
  46. ArgsMightBeOK:
  47.  
  48. ; Fetch the -a switch and check if at least one file present.
  49.  
  50.        MOVE.L  4(A2),AppendBool
  51.        BEQ.S   ArgsOK
  52.        LEA     HelpMsg(PC),ErrorStrPtr
  53.        MOVEQ   #1,D1
  54.        CMP.L   D0,D1
  55.        BEQ     ErrorExit
  56. ArgsOK:
  57.  
  58. ; Alloc tracked mem for the read write buf and the handles.
  59.  
  60.        LEA     OutOfMem(PC),ErrorStrPtr
  61.        ADDQ.L  #1+1,D0                 ; Make space for StdOut + null termination
  62.        LSL.L   #2,D0                   ; in the file handles longword array.
  63.        ADD.L   #BufSize,D0             ; Buffer and Handles use same mem allocation
  64.        MOVEQ   #0,D1
  65.        CALL    ArpAllocMem
  66.        MOVE.L  D0,AllocStruct          ; Data reg, so Z gets set
  67.        BEQ     ErrorExit
  68.  
  69. ; Initialize the handle and filename longword array pointers
  70.  
  71.        MOVE.L  ArgArray(GP),FileNamePtrPtr
  72.        MOVE.L  AllocStruct,A0
  73.        LEA     Handles(A0),HandlePtr
  74.  
  75. ; Open the standard input and output
  76.  
  77.        CALL    Input
  78.        MOVE.L  D0,StdInput
  79.        CALL    Output
  80.        MOVE.L  D0,(HandlePtr)+
  81.  
  82.  
  83. ;----- The open the files, and seek to end loop
  84.  
  85.        LEA     OpenError(PC),ErrorStrPtr
  86. OpenNextFile:
  87.        TST.L   (FileNamePtrPtr)
  88.        BEQ.S   AllFilesOpened
  89.  
  90. ; If Appending, try to open (tracked) the file as an old file
  91.  
  92.        TST.L   AppendBool
  93.        BEQ.S   NoAppendingRequested
  94.        MOVE.L  (FileNamePtrPtr),D1
  95.        MOVE.L  #MODE_OLDFILE,D2
  96.        CALL    ArpOpen
  97.        MOVE.L  D0,(HandlePtr)
  98.        BEQ.S   TryToOpenNewFile
  99.  
  100. ; Seek to the end
  101.  
  102.        MOVE.L  D0,D1
  103.        MOVEQ   #0,D2
  104.        MOVE.L  #OFFSET_END,D3
  105.        CALL    Seek
  106.        ADDQ.L  #1,D0
  107.        BEQ     ErrorExit
  108.        BRA.S   IncrementAndLoop
  109. NoAppendingRequested:
  110.  
  111. ; Open files (tracked) as new
  112.  
  113. TryToOpenNewFile:
  114.        MOVE.L  (FileNamePtrPtr),D1
  115.        MOVE.L  #MODE_NEWFILE,D2
  116.        CALL    ArpOpen
  117.        MOVE.L  D0,(HandlePtr)
  118.        BEQ     ErrorExit
  119.  
  120. ; Update pointers and loop back
  121.  
  122. IncrementAndLoop:
  123.        ADDQ.L  #4,FileNamePtrPtr
  124.        ADDQ.L  #4,HandlePtr
  125.        BRA     OpenNextFile
  126. AllFilesOpened:
  127.        CLR.L   (HandlePtr)                             ; Null termination
  128.  
  129.  
  130. ;----- The single input multi output copy loop, check for ^C & initize
  131.  
  132. DoNextRdWrChunk:
  133.        SUB.L   A1,A1
  134.        CALL    CheckAbort
  135.        MOVE.L  A1,ErrorStrPtr
  136.        TST.L   D0
  137.        BNE.S   ErrorExit
  138.  
  139.        LEA     WriteError(PC),ErrorStrPtr
  140.        MOVE.L  AllocStruct,A0
  141.        LEA     Handles(A0),HandlePtr                   ; Reset to start of array
  142.  
  143. ; Read from the standard input until EOF or error
  144.  
  145.        MOVE.L  StdInput,D1
  146.        MOVE.L  AllocStruct,D2
  147.        MOVE.L  #BufSize,D3
  148.        CALL    Read
  149.        MOVE.L  D0,ActualLength
  150.        BEQ.S   Exit
  151.        BMI.S   ErrorExit
  152.  
  153. ; Do the multiwrite, and loop back
  154.  
  155. DoNextWrite:
  156.        MOVE.L  (HandlePtr)+,D1
  157.        BEQ     DoNextRdWrChunk
  158.        MOVE.L  AllocStruct,D2
  159.        MOVE.L  ActualLength,D3
  160.        CALL    Write
  161.        CMP.L   D0,D3
  162.        BNE.S   ErrorExit
  163.        BRA     DoNextWrite
  164.  
  165.  
  166. ; Done, cleanup
  167.  
  168. Exit:
  169.        CLR.W   ReturnCode(GP)
  170.        SUB.L   ErrorStrPtr,ErrorStrPtr
  171. ErrorExit:
  172.  
  173. ; Display error string, if any, and exit
  174.  
  175.        MOVE.L  ErrorStrPtr,D0
  176.        BEQ.S   NoErrorMsg
  177.        MOVE.L  D0,A1
  178.        CALL    Puts
  179. NoErrorMsg:
  180.        RTS
  181.  
  182. ; The string section
  183.  
  184. Template:
  185.        DC.B    'Files/...,-a=APPEND/s',0
  186. HelpMsg:
  187.        DC.B    'Tee - pipe fitting.',10
  188.        DC.B    'Usage: Tee [-a] <File> [...]',0
  189. OutOfMem:
  190.        DC.B    'Out of memory!',0
  191. OpenError:
  192.        DC.B    'Tee-file could not be opened',10
  193. WriteError:
  194.        DC.B    'Error while writing to tee-file',0
  195.        CNOP    0,2
  196.  
  197.        END
  198.